from curses import wrapper
import logging
import time
from types import WrapperDescriptorType

class LogMixin(object):
    """日志功能Mixin

    配置了一些简单常用的功能方便使用。

    Properties:
        self.logger: logger实例

    """

    def __init__(self):
        super().__init__()
        # 配置类的日志输出
        self.logger = logging.getLogger(name=self.__class__.__name__)
        self.logger.debug('日志Mixin')


class RunTimer(LogMixin):
    """计时器

    配置了一些简单常用的功能方便使用。

    Properties:
        cls.CLS_START_TIME: 计时器类定义时的时间
        self.accuracy: 计时器小数点精度
        self.count: 计时器计时时间

    Functions:
        self.mark(): 计时器打点
        self.cost(): 计时器打点，之后返回与上一次打点之后的时间间隔
        self.log(): 日志形式显示self.cost()的结果

    """
    # 初始打点
    CLS_START_TIME = time.time()

    def __init__(self):
        super().__init__()

        self.__time_accuracy = 2
        self.__mark = self.CLS_START_TIME

    def mark(self, msg=None):
        """计时器打点"""
        if msg is None:
            self.logger.debug('计时器打点')
        else:
            self.logger.info(msg)
        self.__mark = time.time()

    def cost(self):
        """打点后返回上一次打点到现在的时间间隔"""
        time_cost = time.time() - self.__mark
        self.mark()
        return time_cost

    def log(self):
        """日志输出时间

        需要和Timer.mark()配合使用，计时器打点，之后返回与上一次打点之后的时间间隔

        """
        self.logger.info(f"花费时间：{self.cost():.{self.__time_accuracy}f}s")


class TimerMixin():
    """计时器功能Mixin"""

    def __init__(self) -> None:
        super().__init__()
        self.timer = RunTimer()
        self.timer.mark()

    # TODO: 使用装饰器实现函数运行开始和结束的计时日志功能
    # FIXME: 以下函数不工作
    # @WrapperDescriptorType
    # @staticmethod
    # def watch(func):
    #     """计时装饰器
        
    #     需要继承了TimerMixin的类，推荐使用`@{类名}.watch`实现装饰器
        
    #     """
    #     def wrapper(*args, **kwargs):
    #         timer = RunTimer()
    #         timer.mark()
    #         timer.info(f"{func.__name__}开始执行")
    #         result = func(*args, **kwargs)
    #         timer.log()
    #         return result
    #     return wrapper